import 'dart:async';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

typedef BottomBarLayoutBuilder = Widget Function(KeyboardState keyboardState, double keyboardRealTimeHeight, double keyboardHeight);
/// 用于处理底栏有输入框的布局
class BottomBarLayout extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => BottomBarLayoutState();
}

enum KeyboardState {
  hidden, animating, opened
}
class BottomBarLayoutState extends State<BottomBarLayout> {
  Widget _bottomBar;
  Widget _bottomPanel;
  double _keyboardHeight = 0;
  double _realTimeKeyboardHeight = 0;
  bool _showBottomPanel =  false;
  KeyboardState _keyboardState;
  final _channel = SystemChannels.textInput;
  Timer _keyboardHeightTask;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    _handleKeyboardState(context);
    MediaQueryData data = MediaQuery.of(context);
    _bottomBar = Container(
      color: Colors.black12,
      child: Row (
        mainAxisSize: MainAxisSize.max,
        children: [
          Expanded(
            child: TextField(),
          ),
          TextButton(
              onPressed: () {
                _showBottomPanel = !_showBottomPanel;
                if (_showBottomPanel) {
                  hideKeyboard();
                } else {
                }
                setState(() {});
              },
              child: Text(_showBottomPanel ? "关闭底栏" : "打开底栏")),
        ],
      ),
    );
    _bottomPanel = Container(
      height: _keyboardHeight,
      color: Colors.blue,
      child: Center(
        child: Text("我是BottomPanel"),
      ),
    );
    return Container(
      color: Colors.amber,
      child: SafeArea(
        top: false,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [_bottomBar, _showBottomPanel ? _bottomPanel : Container(height: data.viewInsets.bottom,)],
        ),
      ),
    );
  }

  void hideKeyboard() {
    _channel.invokeMethod('TextInput.hide');
  }

  void showKeyboard() {
    _channel.invokeMethod('TextInput.show');
  }

  static const minKeyboardChangeConfirmTime = 64;
  int _lastChangeTime = 0;
  int _keyboardStateConfirmDeltaTime = minKeyboardChangeConfirmTime;
  int _maxKeyboardChangeDeltaTime = 0;
  void _handleKeyboardState(BuildContext context) {
    MediaQueryData data = MediaQuery.of(context);
    int now = DateTime.now().millisecondsSinceEpoch;
    if (data.viewInsets.bottom != _realTimeKeyboardHeight) {
      // 软键盘高度发生了变化
      int deltaTime = now - _lastChangeTime;
      if (_lastChangeTime != 0 && _maxKeyboardChangeDeltaTime < deltaTime) {
        // 记录软键盘高度变化的动画过程中，两次变化的最大时间间隔，通过这个时间间隔来求得软键盘状态确认时间间隔
        _maxKeyboardChangeDeltaTime = deltaTime;
      }
      _lastChangeTime = now;
      _keyboardState = KeyboardState.animating;
      _realTimeKeyboardHeight = data.viewInsets.bottom;
      _keyboardHeightTask?.cancel();
      _keyboardHeightTask = Timer(Duration(milliseconds: _keyboardStateConfirmDeltaTime), _confirmKeyboardState);
    }
  }

  void _confirmKeyboardState() {
    print("确认软键盘状态====>realTimeKeyboardHeight=$_realTimeKeyboardHeight");
    // 更新软键盘高度变化确认间隔时间
    _keyboardStateConfirmDeltaTime = max(64, minKeyboardChangeConfirmTime + 17);
    _lastChangeTime = 0;
    _maxKeyboardChangeDeltaTime = 0;
    print("新的软键盘高度确认时间为：$_keyboardStateConfirmDeltaTime");
    if (_realTimeKeyboardHeight == 0) {
      _keyboardState = KeyboardState.hidden;
      print("软键盘隐藏");
      _onKeyboardHidden();
      return;
    }
    _keyboardHeight = _realTimeKeyboardHeight;
    _keyboardState = KeyboardState.opened;
    print("软键盘已打开");
    _onKeyboardOpened();
  }

  void _onKeyboardHidden() {

  }

  void _onKeyboardOpened() {
    setState(() {
      _showBottomPanel = false;
    });
  }
}
